using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace StarSkipGame
{
    /// <summary>
    /// 成就类型枚举
    /// </summary>
    public enum AchievementType
    {
        TimeSurvived,       // 生存时间
        AsteroidsAvoided,   // 躲避陨石数量
        GamesPlayed,        // 游戏次数
        HighScore,          // 高分记录
        GameModeCompleted,  // 游戏模式完成
        PerfectGame,        // 完美游戏
        SpeedRun,           // 速通
        Marathon            // 马拉松
    }

    /// <summary>
    /// 成就类
    /// </summary>
    public class Achievement
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public AchievementType Type { get; set; }
        public float Requirement { get; set; }
        public bool IsUnlocked { get; set; }
        public DateTime UnlockDate { get; set; }
        public string IconPath { get; set; }
        public int Points { get; set; }

        public Achievement()
        {
            IsUnlocked = false;
            Points = 0;
        }

        public Achievement(string id, string name, string description, AchievementType type, float requirement, int points = 0)
        {
            Id = id;
            Name = name;
            Description = description;
            Type = type;
            Requirement = requirement;
            Points = points;
            IsUnlocked = false;
        }

        public override string ToString()
        {
            return string.Format("{0}: {1} - {2}", 
                IsUnlocked ? "✓" : "✗", Name, Description);
        }
    }

    /// <summary>
    /// 成就系统类
    /// </summary>
    public class AchievementSystem
    {
        private const string ACHIEVEMENT_FILE = "achievements.txt";
        private Dictionary<string, Achievement> achievements;
        private Dictionary<AchievementType, float> progress;

        public Dictionary<string, Achievement> Achievements
        {
            get { return achievements; }
        }

        public AchievementSystem()
        {
            achievements = new Dictionary<string, Achievement>();
            progress = new Dictionary<AchievementType, float>();
            InitializeAchievements();
            LoadProgress();
        }

        /// <summary>
        /// 初始化所有成就
        /// </summary>
        private void InitializeAchievements()
        {
            // 生存时间成就
            AddAchievement(new Achievement("survive_10s", "初学者", "生存10秒", AchievementType.TimeSurvived, 10, 10));
            AddAchievement(new Achievement("survive_30s", "熟练者", "生存30秒", AchievementType.TimeSurvived, 30, 25));
            AddAchievement(new Achievement("survive_60s", "专家", "生存1分钟", AchievementType.TimeSurvived, 60, 50));
            AddAchievement(new Achievement("survive_120s", "大师", "生存2分钟", AchievementType.TimeSurvived, 120, 100));
            AddAchievement(new Achievement("survive_300s", "传奇", "生存5分钟", AchievementType.TimeSurvived, 300, 250));

            // 躲避陨石成就
            AddAchievement(new Achievement("avoid_10", "幸运儿", "成功躲避10个陨石", AchievementType.AsteroidsAvoided, 10, 15));
            AddAchievement(new Achievement("avoid_50", "躲避专家", "成功躲避50个陨石", AchievementType.AsteroidsAvoided, 50, 50));
            AddAchievement(new Achievement("avoid_100", "躲避大师", "成功躲避100个陨石", AchievementType.AsteroidsAvoided, 100, 100));
            AddAchievement(new Achievement("avoid_500", "躲避传奇", "成功躲避500个陨石", AchievementType.AsteroidsAvoided, 500, 250));

            // 游戏次数成就
            AddAchievement(new Achievement("play_5", "新手玩家", "完成5局游戏", AchievementType.GamesPlayed, 5, 20));
            AddAchievement(new Achievement("play_20", "经验玩家", "完成20局游戏", AchievementType.GamesPlayed, 20, 50));
            AddAchievement(new Achievement("play_50", "资深玩家", "完成50局游戏", AchievementType.GamesPlayed, 50, 100));
            AddAchievement(new Achievement("play_100", "游戏达人", "完成100局游戏", AchievementType.GamesPlayed, 100, 200));

            // 高分成就
            AddAchievement(new Achievement("score_100", "高分新手", "获得100分", AchievementType.HighScore, 100, 30));
            AddAchievement(new Achievement("score_500", "高分专家", "获得500分", AchievementType.HighScore, 500, 75));
            AddAchievement(new Achievement("score_1000", "高分大师", "获得1000分", AchievementType.HighScore, 1000, 150));
            AddAchievement(new Achievement("score_2000", "高分传奇", "获得2000分", AchievementType.HighScore, 2000, 300));

            // 游戏模式成就
            AddAchievement(new Achievement("mode_classic", "经典玩家", "完成经典模式", AchievementType.GameModeCompleted, 1, 50));
            AddAchievement(new Achievement("mode_survival", "生存专家", "完成生存模式", AchievementType.GameModeCompleted, 2, 100));
            AddAchievement(new Achievement("mode_timeattack", "时间大师", "完成时间挑战", AchievementType.GameModeCompleted, 3, 150));
            AddAchievement(new Achievement("mode_endless", "无尽挑战者", "完成无尽模式", AchievementType.GameModeCompleted, 4, 200));
            AddAchievement(new Achievement("mode_bossrush", "Boss杀手", "完成Boss挑战", AchievementType.GameModeCompleted, 5, 250));

            // 特殊成就
            AddAchievement(new Achievement("perfect_60s", "完美60秒", "在60秒内不碰撞任何陨石", AchievementType.PerfectGame, 60, 200));
            AddAchievement(new Achievement("speedrun_30s", "速通专家", "在30秒内达到高分", AchievementType.SpeedRun, 30, 150));
            AddAchievement(new Achievement("marathon_600s", "马拉松选手", "生存10分钟", AchievementType.Marathon, 600, 500));
        }

        /// <summary>
        /// 添加成就
        /// </summary>
        /// <param name="achievement">成就对象</param>
        private void AddAchievement(Achievement achievement)
        {
            achievements[achievement.Id] = achievement;
        }

        /// <summary>
        /// 更新进度
        /// </summary>
        /// <param name="type">成就类型</param>
        /// <param name="value">进度值</param>
        public void UpdateProgress(AchievementType type, float value)
        {
            if (!progress.ContainsKey(type))
            {
                progress[type] = 0;
            }

            progress[type] = Math.Max(progress[type], value);
            CheckAchievements(type);
        }

        /// <summary>
        /// 检查成就解锁
        /// </summary>
        /// <param name="type">成就类型</param>
        private void CheckAchievements(AchievementType type)
        {
            var typeAchievements = achievements.Values.Where(a => a.Type == type && !a.IsUnlocked);
            
            foreach (var achievement in typeAchievements)
            {
                if (progress.ContainsKey(type) && progress[type] >= achievement.Requirement)
                {
                    UnlockAchievement(achievement.Id);
                }
            }
        }

        /// <summary>
        /// 解锁成就
        /// </summary>
        /// <param name="achievementId">成就ID</param>
        /// <returns>是否成功解锁</returns>
        public bool UnlockAchievement(string achievementId)
        {
            if (achievements.ContainsKey(achievementId) && !achievements[achievementId].IsUnlocked)
            {
                achievements[achievementId].IsUnlocked = true;
                achievements[achievementId].UnlockDate = DateTime.Now;
                SaveProgress();
                
                // 触发成就解锁事件
                OnAchievementUnlocked(achievements[achievementId]);
                
                return true;
            }
            return false;
        }

        /// <summary>
        /// 获取已解锁的成就数量
        /// </summary>
        /// <returns>已解锁成就数量</returns>
        public int GetUnlockedCount()
        {
            return achievements.Values.Count(a => a.IsUnlocked);
        }

        /// <summary>
        /// 获取总成就数量
        /// </summary>
        /// <returns>总成就数量</returns>
        public int GetTotalCount()
        {
            return achievements.Count;
        }

        /// <summary>
        /// 获取成就完成百分比
        /// </summary>
        /// <returns>完成百分比</returns>
        public float GetCompletionPercentage()
        {
            if (achievements.Count == 0) return 0;
            return (float)GetUnlockedCount() / achievements.Count * 100;
        }

        /// <summary>
        /// 获取总成就点数
        /// </summary>
        /// <returns>总点数</returns>
        public int GetTotalPoints()
        {
            return achievements.Values.Where(a => a.IsUnlocked).Sum(a => a.Points);
        }

        /// <summary>
        /// 获取指定类型的进度
        /// </summary>
        /// <param name="type">成就类型</param>
        /// <returns>进度值</returns>
        public float GetProgress(AchievementType type)
        {
            return progress.ContainsKey(type) ? progress[type] : 0;
        }

        /// <summary>
        /// 获取最近解锁的成就
        /// </summary>
        /// <param name="count">数量</param>
        /// <returns>最近解锁的成就列表</returns>
        public List<Achievement> GetRecentUnlocked(int count = 5)
        {
            return achievements.Values
                .Where(a => a.IsUnlocked)
                .OrderByDescending(a => a.UnlockDate)
                .Take(count)
                .ToList();
        }

        /// <summary>
        /// 获取指定类型的成就
        /// </summary>
        /// <param name="type">成就类型</param>
        /// <returns>成就列表</returns>
        public List<Achievement> GetAchievementsByType(AchievementType type)
        {
            return achievements.Values.Where(a => a.Type == type).ToList();
        }

        /// <summary>
        /// 获取所有成就
        /// </summary>
        /// <returns>所有成就列表</returns>
        public List<Achievement> GetAllAchievements()
        {
            return achievements.Values.ToList();
        }

        /// <summary>
        /// 获取已解锁的成就
        /// </summary>
        /// <returns>已解锁成就列表</returns>
        public List<Achievement> GetUnlockedAchievements()
        {
            return achievements.Values.Where(a => a.IsUnlocked).ToList();
        }

        /// <summary>
        /// 重置所有成就
        /// </summary>
        public void ResetAllAchievements()
        {
            foreach (var achievement in achievements.Values)
            {
                achievement.IsUnlocked = false;
                achievement.UnlockDate = DateTime.MinValue;
            }
            progress.Clear();
            SaveProgress();
        }

        /// <summary>
        /// 从文件加载进度
        /// </summary>
        private void LoadProgress()
        {
            try
            {
                if (!File.Exists(ACHIEVEMENT_FILE))
                    return;

                string[] lines = File.ReadAllLines(ACHIEVEMENT_FILE, Encoding.UTF8);

                foreach (string line in lines)
                {
                    if (string.IsNullOrWhiteSpace(line))
                        continue;

                    try
                    {
                        string[] parts = line.Split('|');
                        if (parts.Length >= 3)
                        {
                            string achievementId = parts[0];
                            bool isUnlocked = bool.Parse(parts[1]);
                            DateTime unlockDate = DateTime.Parse(parts[2]);

                            if (achievements.ContainsKey(achievementId))
                            {
                                achievements[achievementId].IsUnlocked = isUnlocked;
                                achievements[achievementId].UnlockDate = unlockDate;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("解析成就数据失败: " + ex.Message);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("加载成就数据失败: " + ex.Message);
            }
        }

        /// <summary>
        /// 保存进度到文件
        /// </summary>
        private void SaveProgress()
        {
            try
            {
                var lines = achievements.Values.Select(a => 
                    string.Format("{0}|{1}|{2}", 
                        a.Id, 
                        a.IsUnlocked, 
                        a.UnlockDate.ToString("yyyy-MM-dd HH:mm:ss")));

                File.WriteAllLines(ACHIEVEMENT_FILE, lines, Encoding.UTF8);
            }
            catch (Exception ex)
            {
                Console.WriteLine("保存成就数据失败: " + ex.Message);
            }
        }

        // 成就解锁事件
        public event Action<Achievement> AchievementUnlocked;

        /// <summary>
        /// 触发成就解锁事件
        /// </summary>
        /// <param name="achievement">解锁的成就</param>
        protected virtual void OnAchievementUnlocked(Achievement achievement)
        {
            if (AchievementUnlocked != null)
            {
                AchievementUnlocked(achievement);
            }
        }
    }
} 